package cn.aws360.boot.wechat.starter.config;

import cn.aws360.boot.wechat.api.constant.WxmConstant;
import cn.aws360.boot.wechat.api.pojo.request.WxmAppQuery;
import cn.aws360.boot.wechat.api.pojo.response.WxmAppModel;
import cn.aws360.boot.wechat.biz.mp.handler.*;
import cn.aws360.boot.wechat.biz.service.WxmAppService;
import cn.hutool.core.collection.CollUtil;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.List;
import java.util.stream.Collectors;

import static me.chanjar.weixin.common.api.WxConsts.EventType.*;
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType.EVENT;

/**
 * @author junnan
 */
@Configuration
@AllArgsConstructor
public class WxmMpAuthConfiguration {

    private final WxmAppService wxmAppService;
    private final StringRedisTemplate stringRedisTemplate;

    private final WxMpMsgHandler mpMsgHandler;
    private final WxMpEvent4MenuHandler mpMenuHandler;
    private final WxMpEvent4ScanHandler mpScanHandler;
    private final WxMpEvent4FollowHandler mpFollowHandler;
    private final WxMpEvent4LocationHandler mpLocationHandler;

    @Bean
    public WxMpService mpService() {
        List<WxmAppModel> wxmAppModelList = wxmAppService.findList(new WxmAppQuery());
        if (CollUtil.isEmpty(wxmAppModelList)) {
            return null;
        }

        WxMpService mpService = new WxMpServiceImpl();
        RedisTemplateWxRedisOps redisTemplateWxRedisOps = new RedisTemplateWxRedisOps(stringRedisTemplate);
        mpService.setMultiConfigStorages(wxmAppModelList.stream().map(wxmAppModel -> {
            WxMpDefaultConfigImpl configStorage = new WxMpRedisConfigImpl(redisTemplateWxRedisOps, WxmConstant.PREFIX);
            configStorage.setAppId(wxmAppModel.getAppId());
            configStorage.setToken(wxmAppModel.getAppToken());
            configStorage.setSecret(wxmAppModel.getAppSecret());
            configStorage.setAesKey(wxmAppModel.getAppAesKey());
            return configStorage;
        }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
        return mpService;
    }

    @Bean
    public WxMpMessageRouter messageRouter(WxMpService mpService) {
        WxMpMessageRouter wxMpMessageRouter = new WxMpMessageRouter(mpService);

        // 关注事件、取关事件
        wxMpMessageRouter.rule().async(false).msgType(EVENT).event(SUBSCRIBE).handler(mpFollowHandler).end();
        wxMpMessageRouter.rule().async(false).msgType(EVENT).event(UNSUBSCRIBE).handler(mpFollowHandler).end();

        // 扫码事件
        wxMpMessageRouter.rule().async(false).msgType(EVENT).event(SCAN).handler(mpScanHandler).end();

        // 菜单点击事件
        wxMpMessageRouter.rule().async(false).msgType(EVENT).event(CLICK).handler(mpMenuHandler).end();

        // 上报地理位置事件
        wxMpMessageRouter.rule().async(false).msgType(EVENT).event(LOCATION).handler(mpLocationHandler).end();

        // 接收地理位置消息
        wxMpMessageRouter.rule().async(false).msgType(LOCATION).handler(mpLocationHandler).end();

        // 默认文本消息事件
        wxMpMessageRouter.rule().async(false).handler(mpMsgHandler).end();
        return wxMpMessageRouter;
    }

}
